<?php

namespace App\Http\Controllers;

use App\Exceptions\Fail;
use App\Http\Cache\AuthCache;
use App\Http\Cache\RateLimiter;
use App\Models\Menu;
use App\Models\Role;
use App\Models\RoleRelMenu;
use App\Models\User;
use App\Models\UserRelRole;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Context;
use Mews\Captcha\Facades\Captcha;

class AuthController extends Controller
{

    /**
     * @throws Fail
     */
    public function login(Request $request): array
    {
        $params = $request->validate([
            'account' => 'required|string|min:4|max:20',
            'password' => 'required|string|min:6|max:20',
            'captcha' => '',
            'captchaKey' => '',
        ]);
        $limiterKey = md5($request->ip() . $params['account']);
        RateLimiter::check($limiterKey);

        if (!Captcha::check_api($params['captcha'], $params['captchaKey'])) {
            RateLimiter::fail($limiterKey);
            throw new Fail("验证码错误或已过期");
        }

        $user = User::query()->where('account', $params['account'])->get()->toArray()[0] ?? [];
        if (!$user) {
            RateLimiter::fail($limiterKey);
            throw new Fail('账号或密码错误');
        }
        if (!password_verify($params['password'], $user['password'])) {
            RateLimiter::fail($limiterKey);
            throw new Fail('账号或密码错误');
        }
        $token = md5('yg' . time() . $user['id']);
        AuthCache::setUser($token, $user);
        RateLimiter::clear($limiterKey);
        return $this->success(compact('token'));
    }

    public function index(): array
    {
        $data = Context::get('user');
        if ($data['id'] === 1) {
            $data['role_id'] = 9999;
            $data['role_name'] = '超级管理员';
            $data['menus'] = Menu::query()->get()->toArray();
        } else {
            $data['role_id'] = $data['roles'][0]['id'];
            $data['role_name'] = $data['roles'][0]['name'];
            $data['roles'] = Role::query()->whereIn('id', UserRelRole::query()->where('user_id', $data['id'])->pluck('role_id')->toArray())->get()->toArray();
            $data['menus'] = Menu::query()->whereIn('id', RoleRelMenu::query()->where('role_id', $data['role_id'])->pluck('menu_id')->toArray())->get()->toArray();
        }
        unset($data['password']);
        return $this->success($data);
    }

    public function updatePwd(Request $request): array
    {
        $params = $request->validate([
            'opw' => 'required|string',
            'npw' => 'required|string|min:6',
            'npw1' => 'same:npw',
        ]);
        $password = password_hash($params['npw'], PASSWORD_DEFAULT);
        $user = Context::get('user');
        if (!password_verify($params['opw'], $user['password'])) {
            throw new Fail('旧密码错误');
        }
        User::query()->where('id', $user['id'])->update([
            'password' => $password,
        ]);
        $user['password'] = $password;
        AuthCache::setUser(Context::get('token'), $user);
        return $this->success();
    }
}
